package com.bbzn.device.client.controller;

import com.bbzn.device.client.vo.req.IndexReqVO;
import com.bbzn.device.client.vo.res.IndexResVO;
import com.bbzn.device.client.aspect.OperationAnnotation;
import com.bbzn.device.client.dataobject.Product;
import com.bbzn.device.client.dto.device.DeviceDTO;
import com.bbzn.device.client.dto.device.DeviceInfoDTO;
import com.bbzn.device.client.dto.history.AlarmHisDTO;
import com.bbzn.device.client.dto.index.*;
import com.bbzn.device.client.service.*;
import com.bbzn.device.client.utils.*;
import com.bbzn.device.client.utils.date.DateUtil;
import com.bbzn.user.client.UserClient;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author 黄志鹏
 * @Date 2021/3/16 17:11
 * @Version 1.0
 */

@RestController
@Slf4j
@RequestMapping("/index")
//@CrossOrigin
public class IndexController extends BaseApiService {

    @Autowired
    private CommonService commonService;
    @Autowired
    private SystemParamByCacheService systemParamByCacheService;
    @Autowired
    private UserClient userClient;
    @Autowired
    private DeviceService deviceService;
    @Autowired
    private AlarmHisService alarmHisService;
    @Autowired
    private AlarmHisEnService alarmHisEnService;
    @Autowired
    private ProductService productService;
    @Autowired
    private RedisUtils redisUtils;


    /**
     * 返回主页数据
     *
     * @param reqVO
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/getIndexData", method = RequestMethod.POST)
    @OperationAnnotation(content = "进入首页")
    public BaseResponse getIndexData(@RequestBody IndexReqVO reqVO, HttpServletRequest request, HttpServletResponse response) throws Exception {
        String secretKey = commonService.getWebSalt(request);
        String language = MayiktJwtUtils.getLanguage(request, secretKey);
        Long userId = commonService.getUserId(request);
        DeviceDTO deviceDTO = new DeviceDTO();
        deviceDTO.setUserId(userId);
        deviceDTO.setOperatorId(userId);

        IndexResVO indexResVO = new IndexResVO();
        List<DeviceInfoDTO> searchInfos = deviceService.findIndexAll(deviceDTO);
        indexResVO.setDevices(searchInfos);
        List<Long> ids = commonService.getUserIds(userId);
        int total = deviceService.findCountByAll(deviceDTO);
        int month = deviceService.getMonthOnlineCount(deviceDTO);
        deviceDTO.setState(1);
        int online = deviceService.findCountByAll(deviceDTO);
        deviceDTO.setState(2);
        int offline = deviceService.findCountByAll(deviceDTO);
        int active = online + offline;

        List<ProductDevCountDTO> proDevCounts = productService.getProductByDevList(ids);


        indexResVO.setDeviceCount(total);
        indexResVO.setActiveDeviceCount(active);
        indexResVO.setOnLineDeviceCount(online);
        indexResVO.setOffLineDeviceCount(offline);
        indexResVO.setOnLineForMonDeviceCount(month);

        indexResVO.setProductDevCount(proDevCounts);
        indexResVO.setUserCount(ids == null ? 0 : ids.size());

        List<AlarmRecSevenDTO> alarmRecSevenDTOS = new ArrayList<>();
        AlarmRecSevenDTO alarmRecSeven = new AlarmRecSevenDTO();
        AlarmHisDTO alarmHisDTO = new AlarmHisDTO();
        alarmHisDTO.setAlarmType(18);
        alarmHisDTO.setUserId(userId);
        alarmHisDTO.setOperatorId(userId);
        int sosAlarmCount = 0;
        if (language.equals("EN")) {
            sosAlarmCount = alarmHisEnService.alarmHisEnCount(alarmHisDTO);
        } else {
            sosAlarmCount = alarmHisService.alarmHisCount(alarmHisDTO);
        }
        indexResVO.setSosAlarmCount(sosAlarmCount);


        List<DevRecSevenDetailInfoDTO> devRecSevenDetailInfoDTOS = getDevPVByTenantId(userId);
        alarmRecSeven.setDeviceUsed(devRecSevenDetailInfoDTOS);
        List<DevRecSevenDetailInfoDTO> helmetDevUsed = getHelmetDevPVByTenantId(userId);
        alarmRecSeven.setHelmetDevUsed(helmetDevUsed);
        List<DevRecSevenDetailInfoDTO> visitsUsed = getVisitsUserPVByTenantId(userId);
        alarmRecSeven.setVisitsUsed(visitsUsed);
        alarmRecSevenDTOS.add(alarmRecSeven);
        indexResVO.setAlarmRecSevenDTOS(alarmRecSevenDTOS);

        return setResultSuccess(indexResVO);
    }


    public List<DevRecSevenDetailInfoDTO> getVisitsUserPVAdmin() {
        List<Date> dates = DateUtil.getDaysBetwwen(6);
        List<DevRecSevenDetailInfoDTO> devRecSevenDetailInfoDTOS = dates.stream().map(date -> VisitsUserParseDateIndex(date, 0L)).collect(Collectors.toList());
        return devRecSevenDetailInfoDTOS;
    }

    public List<DevRecSevenDetailInfoDTO> getHelmetDevPVAdmin() {
        List<Date> dates = DateUtil.getDaysBetwwen(6);
        List<DevRecSevenDetailInfoDTO> devRecSevenDetailInfoDTOS = dates.stream().map(date -> HelmetDevParseDateIndex(date, 0L)).collect(Collectors.toList());
        return devRecSevenDetailInfoDTOS;
    }

    public List<DevRecSevenDetailInfoDTO> getHelmetDevPVByTenantId(Long tenantId) {
        List<Date> dates = DateUtil.getDaysBetwwen(6);
        List<DevRecSevenDetailInfoDTO> devRecSevenDetailInfoDTOS = dates.stream().map(date -> HelmetDevParseDateIndex(date, tenantId)).collect(Collectors.toList());
        return devRecSevenDetailInfoDTOS;
    }


    private DevRecSevenDetailInfoDTO HelmetDevParseDateIndex(Date date, Long tenantId) {
        DevRecSevenDetailInfoDTO devRecSevenDetailInfoDTO = new DevRecSevenDetailInfoDTO();
        String dateStr = DateUtils.formatDate(date, "yyyy-MM-dd");
        Map<String, String> map = redisUtils.hGetAll("HelmetDevUsedCount:" + tenantId + ":" + dateStr);
        if (null == map || map.size() == 0) {
            devRecSevenDetailInfoDTO.setDays(dateStr);
            devRecSevenDetailInfoDTO.setHelmetDevSevenDetailInfoDTOS(null);
            return devRecSevenDetailInfoDTO;
        }
        List<HelmetDevSevenDetailInfoDTO> helmetDevSevenDetailInfoDTOS = new ArrayList<>();
        for (Map.Entry<String, String> dataStr : map.entrySet()) {
            HelmetDevSevenDetailInfoDTO helmetDevSevenDetailInfoDTO = new HelmetDevSevenDetailInfoDTO();
            helmetDevSevenDetailInfoDTO.setColor(dataStr.getKey());
            helmetDevSevenDetailInfoDTO.setCount(Integer.parseInt(dataStr.getValue()));
            helmetDevSevenDetailInfoDTOS.add(helmetDevSevenDetailInfoDTO);
        }
        devRecSevenDetailInfoDTO.setDays(dateStr);
        devRecSevenDetailInfoDTO.setHelmetDevSevenDetailInfoDTOS(helmetDevSevenDetailInfoDTOS);
        return devRecSevenDetailInfoDTO;
    }


    private DevRecSevenDetailInfoDTO VisitsUserParseDateIndex(Date date, Long tenantId) {
        DevRecSevenDetailInfoDTO devRecSevenDetailInfoDTO = new DevRecSevenDetailInfoDTO();
        String dateStr = DateUtils.formatDate(date, "yyyy-MM-dd");
        Map<String, String> map = redisUtils.hGetAll("visitsCount:" + tenantId + ":" + dateStr);
        if (null == map || map.size() == 0) {
            devRecSevenDetailInfoDTO.setDays(dateStr);
            devRecSevenDetailInfoDTO.setVisitsCount(0);
            return devRecSevenDetailInfoDTO;
        }
        int count = 0;
        for (Map.Entry<String, String> dataStr : map.entrySet()) {
            devRecSevenDetailInfoDTO.setDays(dateStr);
            count += Integer.parseInt(dataStr.getValue());
            //devRecSevenDetailInfoDTO.setVisitsCount(Integer.parseInt(dataStr.getValue()));
        }
        devRecSevenDetailInfoDTO.setVisitsCount(count);
        return devRecSevenDetailInfoDTO;
    }

    public List<DevRecSevenDetailInfoDTO> getVisitsUserPVByTenantId(Long tenantId) {
        List<Date> dates = DateUtil.getDaysBetwwen(6);
        List<DevRecSevenDetailInfoDTO> devRecSevenDetailInfoDTOS = dates.stream().map(date -> VisitsUserParseDateIndex(date, tenantId)).collect(Collectors.toList());
        return devRecSevenDetailInfoDTOS;
    }

    public List<DevRecSevenDetailInfoDTO> getDevPVByTenantId(Long tenantId) {
        List<Date> dates = DateUtil.getDaysBetwwen(6);
        List<DevRecSevenDetailInfoDTO> devRecSevenDetailInfoDTOS = dates.stream().map(date -> devParseDateIndex(date, tenantId)).collect(Collectors.toList());
        return devRecSevenDetailInfoDTOS;
    }


    private DevRecSevenDetailInfoDTO devParseDateIndex(Date date, Long tenantId) {
        DevRecSevenDetailInfoDTO devRecSevenDetailInfoDTO = new DevRecSevenDetailInfoDTO();
        String dateStr = DateUtils.formatDate(date, "yyyy-MM-dd");
        Map<String, String> map = redisUtils.hGetAll("DeviceUsedCount:" + tenantId + ":" + dateStr);
        if (null == map || map.size() == 0) {
            devRecSevenDetailInfoDTO.setDays(dateStr);
            devRecSevenDetailInfoDTO.setDevSevenDetailInfoDTOS(null);
            return devRecSevenDetailInfoDTO;
        }
        List<DevSevenDetailInfoDTO> devSevenDetailInfoDTOS = new ArrayList<>();
        for (Map.Entry<String, String> dataStr : map.entrySet()) {
            DevSevenDetailInfoDTO devSevenDetailInfoDTO = new DevSevenDetailInfoDTO();
            Product product = productService.selectByPrimaryKey(Long.parseLong(dataStr.getKey()));
            devSevenDetailInfoDTO.setProductName(product.getProductName());
            devSevenDetailInfoDTO.setCount(Integer.parseInt(dataStr.getValue()));
            devSevenDetailInfoDTOS.add(devSevenDetailInfoDTO);
        }
        devRecSevenDetailInfoDTO.setDays(dateStr);
        devRecSevenDetailInfoDTO.setDevSevenDetailInfoDTOS(devSevenDetailInfoDTOS);
        return devRecSevenDetailInfoDTO;
    }

    /**
     * 根据Token获取用户手机号
     *
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/getPhoneByToken", method = RequestMethod.POST)
    //@OperationAnnotation(content = "根据Token获取用户手机号")    这里不能加日志，不然会跟getAppSalt冲突有问题
    public BaseResponse getPhoneByToken(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String secretKey = commonService.getAppSalt(request);
        String phone = MayiktJwtUtils.getPhone(request, secretKey);
        return setResultSuccess("success", phone);
    }
}
